{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# TensorFlow Tutorial #03-C\n",
    "# Keras API\n",
    "\n",
    "by [Magnus Erik Hvass Pedersen](http://www.hvass-labs.org/)\n",
    "/ [GitHub](https://github.com/Hvass-Labs/TensorFlow-Tutorials) / [Videos on YouTube](https://www.youtube.com/playlist?list=PL9Hr9sNUjfsmEu1ZniY0XpHSzl5uihcXZ)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Introduction\n",
    "\n",
    "Tutorial #02 showed how to implement a Convolutional Neural Network in TensorFlow. We made a few helper-functions for creating the layers in the network. It is essential to have a good high-level API because it makes it much easier to implement complex models, and it lowers the risk of errors.\n",
    "\n",
    "There are several of these builder API's available for TensorFlow: PrettyTensor (Tutorial #03), Layers API (Tutorial #03-B), and several others. But they were never really finished and now they seem to be more or less abandoned by their developers.\n",
    "\n",
    "This tutorial is about the Keras API which is already highly developed with very good documentation - and the development continues. It seems likely that Keras will be the standard API for TensorFlow in the future so it is recommended that you use it instead of the other APIs.\n",
    "\n",
    "The author of Keras has written a [blog-post](https://blog.keras.io/user-experience-design-for-apis.html) on his API design philosophy which you should read."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Flowchart"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The following chart shows roughly how the data flows in the Convolutional Neural Network that is implemented below. See Tutorial #02 for a more detailed description of convolution.\n",
    "\n",
    "There are two convolutional layers, each followed by a down-sampling using max-pooling (not shown in this flowchart). Then there are two fully-connected layers ending in a softmax-classifier."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![Flowchart](images/02_network_flowchart.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "import tensorflow as tf\n",
    "import numpy as np\n",
    "import math"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We need to import several things from Keras."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from tensorflow.keras.models import Sequential\n",
    "from tensorflow.keras.layers import InputLayer, Input\n",
    "from tensorflow.keras.layers import Reshape, MaxPooling2D\n",
    "from tensorflow.keras.layers import Conv2D, Dense, Flatten"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This was developed using Python 3.6 (Anaconda) and TensorFlow version:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'2.1.0'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.__version__"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load Data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The MNIST data-set is about 12 MB and will be downloaded automatically if it is not located in the given path."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from mnist import MNIST\n",
    "data = MNIST(data_dir=\"data/MNIST/\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The MNIST data-set has now been loaded and consists of 70.000 images and class-numbers for the images. The data-set is split into 3 mutually exclusive sub-sets. We will only use the training and test-sets in this tutorial."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Size of:\n",
      "- Training-set:\t\t55000\n",
      "- Validation-set:\t5000\n",
      "- Test-set:\t\t10000\n"
     ]
    }
   ],
   "source": [
    "print(\"Size of:\")\n",
    "print(\"- Training-set:\\t\\t{}\".format(data.num_train))\n",
    "print(\"- Validation-set:\\t{}\".format(data.num_val))\n",
    "print(\"- Test-set:\\t\\t{}\".format(data.num_test))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Copy some of the data-dimensions for convenience."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# The number of pixels in each dimension of an image.\n",
    "img_size = data.img_size\n",
    "\n",
    "# The images are stored in one-dimensional arrays of this length.\n",
    "img_size_flat = data.img_size_flat\n",
    "\n",
    "# Tuple with height and width of images used to reshape arrays.\n",
    "img_shape = data.img_shape\n",
    "\n",
    "# Tuple with height, width and depth used to reshape arrays.\n",
    "# This is used for reshaping in Keras.\n",
    "img_shape_full = data.img_shape_full\n",
    "\n",
    "# Number of classes, one class for each of 10 digits.\n",
    "num_classes = data.num_classes\n",
    "\n",
    "# Number of colour channels for the images: 1 channel for gray-scale.\n",
    "num_channels = data.num_channels"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Helper-function for plotting images"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Function used to plot 9 images in a 3x3 grid, and writing the true and predicted classes below each image."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_images(images, cls_true, cls_pred=None):\n",
    "    assert len(images) == len(cls_true) == 9\n",
    "    \n",
    "    # Create figure with 3x3 sub-plots.\n",
    "    fig, axes = plt.subplots(3, 3)\n",
    "    fig.subplots_adjust(hspace=0.3, wspace=0.3)\n",
    "\n",
    "    for i, ax in enumerate(axes.flat):\n",
    "        # Plot image.\n",
    "        ax.imshow(images[i].reshape(img_shape), cmap='binary')\n",
    "\n",
    "        # Show true and predicted classes.\n",
    "        if cls_pred is None:\n",
    "            xlabel = \"True: {0}\".format(cls_true[i])\n",
    "        else:\n",
    "            xlabel = \"True: {0}, Pred: {1}\".format(cls_true[i], cls_pred[i])\n",
    "\n",
    "        # Show the classes as the label on the x-axis.\n",
    "        ax.set_xlabel(xlabel)\n",
    "        \n",
    "        # Remove ticks from the plot.\n",
    "        ax.set_xticks([])\n",
    "        ax.set_yticks([])\n",
    "    \n",
    "    # Ensure the plot is shown correctly with multiple plots\n",
    "    # in a single Notebook cell.\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Plot a few images to see if data is correct"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 9 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Get the first images from the test-set.\n",
    "images = data.x_test[0:9]\n",
    "\n",
    "# Get the true classes for those images.\n",
    "cls_true = data.y_test_cls[0:9]\n",
    "\n",
    "# Plot the images and labels using our helper-function above.\n",
    "plot_images(images=images, cls_true=cls_true)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Helper-function to plot example errors\n",
    "\n",
    "Function for plotting examples of images from the test-set that have been mis-classified."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_example_errors(cls_pred):\n",
    "    # cls_pred is an array of the predicted class-number for\n",
    "    # all images in the test-set.\n",
    "\n",
    "    # Boolean array whether the predicted class is incorrect.\n",
    "    incorrect = (cls_pred != data.y_test_cls)\n",
    "\n",
    "    # Get the images from the test-set that have been\n",
    "    # incorrectly classified.\n",
    "    images = data.x_test[incorrect]\n",
    "    \n",
    "    # Get the predicted classes for those images.\n",
    "    cls_pred = cls_pred[incorrect]\n",
    "\n",
    "    # Get the true classes for those images.\n",
    "    cls_true = data.y_test_cls[incorrect]\n",
    "    \n",
    "    # Plot the first 9 images.\n",
    "    plot_images(images=images[0:9],\n",
    "                cls_true=cls_true[0:9],\n",
    "                cls_pred=cls_pred[0:9])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## PrettyTensor API\n",
    "\n",
    "This is how the Convolutional Neural Network was implemented in Tutorial #03 using the PrettyTensor API. It is shown here for easy comparison to the Keras implementation below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "if False:\n",
    "    x_pretty = pt.wrap(x_image)\n",
    "\n",
    "    with pt.defaults_scope(activation_fn=tf.nn.relu):\n",
    "        y_pred, loss = x_pretty.\\\n",
    "            conv2d(kernel=5, depth=16, name='layer_conv1').\\\n",
    "            max_pool(kernel=2, stride=2).\\\n",
    "            conv2d(kernel=5, depth=36, name='layer_conv2').\\\n",
    "            max_pool(kernel=2, stride=2).\\\n",
    "            flatten().\\\n",
    "            fully_connected(size=128, name='layer_fc1').\\\n",
    "            softmax_classifier(num_classes=num_classes, labels=y_true)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sequential Model\n",
    "\n",
    "The Keras API has two modes of constructing Neural Networks. The simplest is the Sequential Model which only allows for the layers to be added in sequence."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# Start construction of the Keras Sequential model.\n",
    "model = Sequential()\n",
    "\n",
    "# Add an input layer which is similar to a feed_dict in TensorFlow.\n",
    "# Note that the input-shape must be a tuple containing the image-size.\n",
    "model.add(InputLayer(input_shape=(img_size_flat,)))\n",
    "\n",
    "# The input is a flattened array with 784 elements,\n",
    "# but the convolutional layers expect images with shape (28, 28, 1)\n",
    "model.add(Reshape(img_shape_full))\n",
    "\n",
    "# First convolutional layer with ReLU-activation and max-pooling.\n",
    "model.add(Conv2D(kernel_size=5, strides=1, filters=16, padding='same',\n",
    "                 activation='relu', name='layer_conv1'))\n",
    "model.add(MaxPooling2D(pool_size=2, strides=2))\n",
    "\n",
    "# Second convolutional layer with ReLU-activation and max-pooling.\n",
    "model.add(Conv2D(kernel_size=5, strides=1, filters=36, padding='same',\n",
    "                 activation='relu', name='layer_conv2'))\n",
    "model.add(MaxPooling2D(pool_size=2, strides=2))\n",
    "\n",
    "# Flatten the 4-rank output of the convolutional layers\n",
    "# to 2-rank that can be input to a fully-connected / dense layer.\n",
    "model.add(Flatten())\n",
    "\n",
    "# First fully-connected / dense layer with ReLU-activation.\n",
    "model.add(Dense(128, activation='relu'))\n",
    "\n",
    "# Last fully-connected / dense layer with softmax-activation\n",
    "# for use in classification.\n",
    "model.add(Dense(num_classes, activation='softmax'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Model Compilation\n",
    "\n",
    "The Neural Network has now been defined and must be finalized by adding a loss-function, optimizer and performance metrics. This is called model \"compilation\" in Keras.\n",
    "\n",
    "We can either define the optimizer using a string, or if we want more control of its parameters then we need to instantiate an object. For example, we can set the learning-rate."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "from tensorflow.keras.optimizers import Adam\n",
    "\n",
    "optimizer = Adam(lr=1e-3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For a classification-problem such as MNIST which has 10 possible classes, we need to use the loss-function called `categorical_crossentropy`. The performance metric we are interested in is the classification accuracy."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.compile(optimizer=optimizer,\n",
    "              loss='categorical_crossentropy',\n",
    "              metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Training\n",
    "\n",
    "Now that the model has been fully defined with loss-function and optimizer, we can train it. This function takes numpy-arrays and performs the given number of training epochs using the given batch-size. An epoch is one full use of the entire training-set. So for 10 epochs we would iterate randomly over the entire training-set 10 times."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 55000 samples\n",
      "55000/55000 [==============================] - 21s 375us/sample - loss: 0.2251 - accuracy: 0.9335\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<tensorflow.python.keras.callbacks.History at 0x7f815cf3c630>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.fit(x=data.x_train,\n",
    "          y=data.y_train,\n",
    "          epochs=1, batch_size=128)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Evaluation\n",
    "\n",
    "Now that the model has been trained we can test its performance on the test-set. This also uses numpy-arrays as input."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10000/10000 [==============================] - 2s 187us/sample - loss: 0.0771 - accuracy: 0.9756\n"
     ]
    }
   ],
   "source": [
    "result = model.evaluate(x=data.x_test,\n",
    "                        y=data.y_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can print all the performance metrics for the test-set."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loss 0.07707656768076122\n",
      "accuracy 0.9756\n"
     ]
    }
   ],
   "source": [
    "for name, value in zip(model.metrics_names, result):\n",
    "    print(name, value)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Or we can just print the classification accuracy."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "accuracy: 97.56%\n"
     ]
    }
   ],
   "source": [
    "print(\"{0}: {1:.2%}\".format(model.metrics_names[1], result[1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Prediction\n",
    "\n",
    "We can also predict the classification for new images. We will just use some images from the test-set but you could load your own images into numpy arrays and use those instead."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "images = data.x_test[0:9]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "These are the true class-number for those images. This is only used when plotting the images."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "cls_true = data.y_test_cls[0:9]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Get the predicted classes as One-Hot encoded arrays."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred = model.predict(x=images)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Get the predicted classes as integers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "cls_pred = np.argmax(y_pred, axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 9 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_images(images=images,\n",
    "            cls_true=cls_true,\n",
    "            cls_pred=cls_pred)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Examples of Mis-Classified Images\n",
    "\n",
    "We can plot some examples of mis-classified images from the test-set.\n",
    "\n",
    "First we get the predicted classes for all the images in the test-set:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred = model.predict(x=data.x_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then we convert the predicted class-numbers from One-Hot encoded arrays to integers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "cls_pred = np.argmax(y_pred, axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Plot some of the mis-classified images."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 9 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_example_errors(cls_pred)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Functional Model\n",
    "\n",
    "The Keras API can also be used to construct more complicated networks using the Functional Model. This may look a little confusing at first, because each call to the Keras API will create and return an instance that is itself callable. It is not clear whether it is a function or an object - but we can call it as if it is a function. This allows us to build computational graphs that are more complex than the Sequential Model allows."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create an input layer which is similar to a feed_dict in TensorFlow.\n",
    "# Note that the input-shape must be a tuple containing the image-size.\n",
    "inputs = Input(shape=(img_size_flat,))\n",
    "\n",
    "# Variable used for building the Neural Network.\n",
    "net = inputs\n",
    "\n",
    "# The input is an image as a flattened array with 784 elements.\n",
    "# But the convolutional layers expect images with shape (28, 28, 1)\n",
    "net = Reshape(img_shape_full)(net)\n",
    "\n",
    "# First convolutional layer with ReLU-activation and max-pooling.\n",
    "net = Conv2D(kernel_size=5, strides=1, filters=16, padding='same',\n",
    "             activation='relu', name='layer_conv1')(net)\n",
    "net = MaxPooling2D(pool_size=2, strides=2)(net)\n",
    "\n",
    "# Second convolutional layer with ReLU-activation and max-pooling.\n",
    "net = Conv2D(kernel_size=5, strides=1, filters=36, padding='same',\n",
    "             activation='relu', name='layer_conv2')(net)\n",
    "net = MaxPooling2D(pool_size=2, strides=2)(net)\n",
    "\n",
    "# Flatten the output of the conv-layer from 4-dim to 2-dim.\n",
    "net = Flatten()(net)\n",
    "\n",
    "# First fully-connected / dense layer with ReLU-activation.\n",
    "net = Dense(128, activation='relu')(net)\n",
    "\n",
    "# Last fully-connected / dense layer with softmax-activation\n",
    "# so it can be used for classification.\n",
    "net = Dense(num_classes, activation='softmax')(net)\n",
    "\n",
    "# Output of the Neural Network.\n",
    "outputs = net"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Model Compilation\n",
    "\n",
    "We have now defined the architecture of the model with its input and output. We now have to create a Keras model and compile it with a loss-function and optimizer, so it is ready for training."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "from tensorflow.python.keras.models import Model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a new instance of the Keras Functional Model. We give it the inputs and outputs of the Convolutional Neural Network that we constructed above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "model2 = Model(inputs=inputs, outputs=outputs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Compile the Keras model using the RMSprop optimizer and with a loss-function for multiple categories. The only performance metric we are interested in is the classification accuracy, but you could use a list of metrics here."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "model2.compile(optimizer='rmsprop',\n",
    "               loss='categorical_crossentropy',\n",
    "               metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Training\n",
    "\n",
    "The model has now been defined and compiled so it can be trained using the same `fit()` function as used in the Sequential Model above. This also takes numpy-arrays as input."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 55000 samples\n",
      "55000/55000 [==============================] - 16s 298us/sample - loss: 0.1977 - accuracy: 0.9389\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<tensorflow.python.keras.callbacks.History at 0x7f81307d4710>"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model2.fit(x=data.x_train,\n",
    "           y=data.y_train,\n",
    "           epochs=1, batch_size=128)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Evaluation\n",
    "\n",
    "Once the model has been trained we can evaluate its performance on the test-set. This is the same syntax as for the Sequential Model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10000/10000 [==============================] - 2s 169us/sample - loss: 0.0563 - accuracy: 0.9809\n"
     ]
    }
   ],
   "source": [
    "result = model2.evaluate(x=data.x_test,\n",
    "                         y=data.y_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The result is a list of values, containing the loss-value and all the metrics we defined when we compiled the model. Note that 'accuracy' is now called 'acc' which is a small inconsistency."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loss 0.05628199413705152\n",
      "accuracy 0.9809\n"
     ]
    }
   ],
   "source": [
    "for name, value in zip(model2.metrics_names, result):\n",
    "    print(name, value)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also print the classification accuracy as a percentage:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "accuracy: 98.09%\n"
     ]
    }
   ],
   "source": [
    "print(\"{0}: {1:.2%}\".format(model2.metrics_names[1], result[1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Examples of Mis-Classified Images\n",
    "\n",
    "We can plot some examples of mis-classified images from the test-set.\n",
    "\n",
    "First we get the predicted classes for all the images in the test-set:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred = model2.predict(x=data.x_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then we convert the predicted class-numbers from One-Hot encoded arrays to integers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "cls_pred = np.argmax(y_pred, axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Plot some of the mis-classified images."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 9 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_example_errors(cls_pred)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Save & Load Model\n",
    "\n",
    "NOTE: You need to install `h5py` for this to work!\n",
    "\n",
    "Tutorial #04 was about saving and restoring the weights of a model using native TensorFlow code. It was an absolutely horrible API! Fortunately, Keras makes this very easy.\n",
    "\n",
    "This is the file-path where we want to save the Keras model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "path_model = 'model.keras'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Saving a Keras model with the trained weights is then just a single function call, as it should be."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "model2.save(path_model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Delete the model from memory so we are sure it is no longer used."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "del model2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We need to import this Keras function for loading the model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "from tensorflow.python.keras.models import load_model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Loading the model is then just a single function-call, as it should be."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "model3 = load_model(path_model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can then use the model again e.g. to make predictions. We get the first 9 images from the test-set and their true class-numbers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "images = data.x_test[0:9]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "cls_true = data.y_test_cls[0:9]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We then use the restored model to predict the class-numbers for those images."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred = model3.predict(x=images)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Get the class-numbers as integers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [],
   "source": [
    "cls_pred = np.argmax(y_pred, axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Plot the images with their true and predicted class-numbers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 9 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_images(images=images,\n",
    "            cls_pred=cls_pred,\n",
    "            cls_true=cls_true)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Visualization of Layer Weights and Outputs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Helper-function for plotting convolutional weights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_conv_weights(weights, input_channel=0):\n",
    "    # Get the lowest and highest values for the weights.\n",
    "    # This is used to correct the colour intensity across\n",
    "    # the images so they can be compared with each other.\n",
    "    w_min = np.min(weights)\n",
    "    w_max = np.max(weights)\n",
    "\n",
    "    # Number of filters used in the conv. layer.\n",
    "    num_filters = weights.shape[3]\n",
    "\n",
    "    # Number of grids to plot.\n",
    "    # Rounded-up, square-root of the number of filters.\n",
    "    num_grids = math.ceil(math.sqrt(num_filters))\n",
    "    \n",
    "    # Create figure with a grid of sub-plots.\n",
    "    fig, axes = plt.subplots(num_grids, num_grids)\n",
    "\n",
    "    # Plot all the filter-weights.\n",
    "    for i, ax in enumerate(axes.flat):\n",
    "        # Only plot the valid filter-weights.\n",
    "        if i<num_filters:\n",
    "            # Get the weights for the i'th filter of the input channel.\n",
    "            # See new_conv_layer() for details on the format\n",
    "            # of this 4-dim tensor.\n",
    "            img = weights[:, :, input_channel, i]\n",
    "\n",
    "            # Plot image.\n",
    "            ax.imshow(img, vmin=w_min, vmax=w_max,\n",
    "                      interpolation='nearest', cmap='seismic')\n",
    "        \n",
    "        # Remove ticks from the plot.\n",
    "        ax.set_xticks([])\n",
    "        ax.set_yticks([])\n",
    "    \n",
    "    # Ensure the plot is shown correctly with multiple plots\n",
    "    # in a single Notebook cell.\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Get Layers\n",
    "\n",
    "Keras has a simple way of listing the layers in the model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"model\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "input_2 (InputLayer)         [(None, 784)]             0         \n",
      "_________________________________________________________________\n",
      "reshape_1 (Reshape)          (None, 28, 28, 1)         0         \n",
      "_________________________________________________________________\n",
      "layer_conv1 (Conv2D)         (None, 28, 28, 16)        416       \n",
      "_________________________________________________________________\n",
      "max_pooling2d_2 (MaxPooling2 (None, 14, 14, 16)        0         \n",
      "_________________________________________________________________\n",
      "layer_conv2 (Conv2D)         (None, 14, 14, 36)        14436     \n",
      "_________________________________________________________________\n",
      "max_pooling2d_3 (MaxPooling2 (None, 7, 7, 36)          0         \n",
      "_________________________________________________________________\n",
      "flatten_1 (Flatten)          (None, 1764)              0         \n",
      "_________________________________________________________________\n",
      "dense_2 (Dense)              (None, 128)               225920    \n",
      "_________________________________________________________________\n",
      "dense_3 (Dense)              (None, 10)                1290      \n",
      "=================================================================\n",
      "Total params: 242,062\n",
      "Trainable params: 242,062\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model3.summary()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We count the indices to get the layers we want.\n",
    "\n",
    "The input-layer has index 0."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "layer_input = model3.layers[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The first convolutional layer has index 2."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tensorflow.python.keras.layers.convolutional.Conv2D at 0x7f8145dfdf60>"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "layer_conv1 = model3.layers[2]\n",
    "layer_conv1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The second convolutional layer has index 4."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [],
   "source": [
    "layer_conv2 = model3.layers[4]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Convolutional Weights\n",
    "\n",
    "Now that we have the layers we can easily get their weights."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [],
   "source": [
    "weights_conv1 = layer_conv1.get_weights()[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This gives us a 4-rank tensor."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(5, 5, 1, 16)"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "weights_conv1.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Plot the weights using the helper-function from above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 16 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_conv_weights(weights=weights_conv1, input_channel=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also get the weights for the second convolutional layer and plot them."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [],
   "source": [
    "weights_conv2 = layer_conv2.get_weights()[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 36 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_conv_weights(weights=weights_conv2, input_channel=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Helper-function for plotting the output of a convolutional layer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_conv_output(values):\n",
    "    # Number of filters used in the conv. layer.\n",
    "    num_filters = values.shape[3]\n",
    "\n",
    "    # Number of grids to plot.\n",
    "    # Rounded-up, square-root of the number of filters.\n",
    "    num_grids = math.ceil(math.sqrt(num_filters))\n",
    "    \n",
    "    # Create figure with a grid of sub-plots.\n",
    "    fig, axes = plt.subplots(num_grids, num_grids)\n",
    "\n",
    "    # Plot the output images of all the filters.\n",
    "    for i, ax in enumerate(axes.flat):\n",
    "        # Only plot the images for valid filters.\n",
    "        if i<num_filters:\n",
    "            # Get the output image of using the i'th filter.\n",
    "            img = values[0, :, :, i]\n",
    "\n",
    "            # Plot image.\n",
    "            ax.imshow(img, interpolation='nearest', cmap='binary')\n",
    "        \n",
    "        # Remove ticks from the plot.\n",
    "        ax.set_xticks([])\n",
    "        ax.set_yticks([])\n",
    "    \n",
    "    # Ensure the plot is shown correctly with multiple plots\n",
    "    # in a single Notebook cell.\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Input Image\n",
    "\n",
    "Helper-function for plotting a single image."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_image(image):\n",
    "    plt.imshow(image.reshape(img_shape),\n",
    "               interpolation='nearest',\n",
    "               cmap='binary')\n",
    "\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Plot an image from the test-set which will be used as an example below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "image1 = data.x_test[0]\n",
    "plot_image(image1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Output of Convolutional Layer\n",
    "\n",
    "In order to show the output of a convolutional layer, we can create another Functional Model using the same input as the original model, but the output is now taken from the convolutional layer that we are interested in."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "output_conv2 = Model(inputs=layer_input.input,\n",
    "                     outputs=layer_conv2.output)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This creates a new model-object where we can call the typical Keras functions. To get the output of the convoloutional layer we call the `predict()` function with the input image."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 14, 14, 36)"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "layer_output2 = output_conv2.predict(np.array([image1]))\n",
    "layer_output2.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can then plot the images for all 36 channels."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAU8AAADrCAYAAADpNxS+AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAAgAElEQVR4nO2dd3hUVfrHP5NAEgIISGgqEFTAAmvDtSIPrGJZsfe66qrrqqvPrs/PXnfVXXRtj4+9bBEbrrrqWnZt2EFiFwuWgIAKEZAaQ5L5/ZHnvffOMBlm7twyk3w//8zJuXfmnpO5c+57znnf75tIJpMIIYTIj7K4GyCEEKWIBk8hhPCBBk8hhPCBBk8hhPCBBk8hhPCBBk8hhPBBl3xOrqmpSdbW1obUlOzU19fT0NCQCPs6nb2P6a5riUTwzamrq2tIJpP9Av/gNGpqapJDhw5N6ZOVrV+Z+hdEn4vhuwybqPoIxdnPvAbP2tpaZs6cGVyr8mDMmDGRXCdbHxcvXgxA7969ASgrC9Zwj7qPjY2NTl2XLm23woIFC4C2GwagqqrKOWfw4MEAdO/eHSDl/ZWVlSnn29+ZSCQScwrtQy4MHTqUN954gxUrVjh1TU1NADQ3NwNuH+y79WL/k27dujl1ffr0AaBXr14AVFRUpJxrxHm/Ll26FIBFixYBsPHGGwNQXl7e7uf89NNPTrmlpQWA6urqrNeOqo9QnGOPpu1CCOEDDZ5CCOGDvKbtnZ3W1lYg+Ol6XHin5MaQIUNSXrPx448/OmWbGtv0deDAgYA7rY2DRCJBZWVl1iWEjogtK9lrLnSk/9EPP/zglLt27QrAeuutt9Z5a9asAeDrr78GYMSIEWuds3r1aud3n07HGAWEECJiisbyfOeddwDYdtttY25J+9TU1Ph63/fffw/AgAEDgmxO7NgGkhBRYRt9APPnzwfggw8+AOD1118HUjfvzOIcNWoUAP36uU4ejz32GOBujh5xxBEADBo0yDmntrZWlqcQQgRJ7JbnqaeeCsBll10Wb0NC5JVXXgHg0EMPjbklLq2trR1m7bY9mpqamDt3Lu+9955T9/bbbwPw8ccfAzjHbN0LXDekCRMmADBp0iTn2D777ANkn0WYq48IlpaWFj7//HPn76effhqAf/3rX0CbaxrA/vvv75xj65jbbbfdWp9nVuzq1asBGD58OLD2jCrdDc3o2L8eIYQIibwsz9bWVpYvX07Pnj0Da8Add9wBwO233x7YZwaBNyrFT8TJs88+65TNabmYiMPqtCd8VHTt2pX+/funrKNvsMEGAIwbNw6At956K+UV3HUyW/vy7tSmr3+tWrUKSPU8qK6uLjnr0xtI0KNHjxhb0j7l5eUpVuGuu+4KwDnnnOPr83baaScAli1bBmTekc+GLE8hhPCBBk8hhPBBXtP2srKyQKbs9913n1M+++yzC/68MPArDvHtt98CcMkllzh1xx13XCBtioPly5c7ZZvaWcyzbax4efTRRwHYbLPNgNT490znh0kikaCqqoqNNtrIqfOWAXbfffeCrmH/C+/90qVLl1g348w17quvvgLc78C7bGLuOaeffjoABx10kHPMNmCKEe/4s+OOOwbymflO1w1ZnkII4YNYXJWOOeaYjOWOwPXXXw+0OdcaZ5xxRkyt8Y9teHgtRwt1y2ZBmgLRZ599BqQq85i6T0fEq7wE4Uj5ZcO7kWUbPqNHj0455m2TBaWcd955AFx99dWRtDNu5s2b55TTZyH5IstTCCF8EInl+emnnwIwefJkAO65554oLhspd999NwBTp04F4PHHH4+zOQVj62NewYhc1oamT58OuO5ZRx11lHMsH6GKsDArzEQhOooghneN1fRWs2FrhxdddFHO1yjUfS9O7r33XgA++ugjp+6vf/1rQZ8py1MIIXygwVMIIXwQybTd3JEsmqijYJsi4PbNoh622mqrWNpUKCtXrgRcTUSLF14Xr776KuBOi+3/MHLkyKCbWBBBTdctbUUpTfv/8pe/OOVcv1cvpTZVB5gzpy3jy5133gkUPlX3IstTCCF8EJrlecEFFzhlc3HJRZ28lPjDH/7glGfMmAG4Gyalim025LLp4MVcX8y1yZzko3aMXxdBWYqlZHEalrwOXO3Kjs72228PwCabbAK48exBIMtTCCF8EJrl6X0ye9daOgKWvtbW+QBOO+20uJoTGy+//LJTfv/99wHYY489ABg2bFgcTRJZOOWUU/I632YRmXJdFTOm8wlu+uW5c+cGfh1ZnkII4YPQLM9LL700rI+OHRNeuPjii506v5qCxYI5tZu1YdkvM2FBD4888ohTZ6GAO++8M5D/mmlUmDeBOUt/8sknAKy//vrOORZGakrjpgEK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\n",
      "text/plain": [
       "<Figure size 432x288 with 36 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_conv_output(values=layer_output2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Conclusion\n",
    "\n",
    "This tutorial showed how to use the so-called *Keras API* for easily building Convolutional Neural Networks in TensorFlow. Keras is by far the most complete and best designed API for TensorFlow.\n",
    "\n",
    "This tutorial also showed how to use Keras to save and load a model, as well as getting the weights and outputs of convolutional layers.\n",
    "\n",
    "It seems likely that Keras will be the standard API for TensorFlow in the future, for the simple reason that is already very good and it is constantly being improved. So it is recommended that you use Keras."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Exercises\n",
    "\n",
    "These are a few suggestions for exercises that may help improve your skills with TensorFlow. It is important to get hands-on experience with TensorFlow in order to learn how to use it properly.\n",
    "\n",
    "You may want to backup this Notebook before making any changes.\n",
    "\n",
    "* Train for more epochs. Does it improve the classification accuracy?\n",
    "* Change the activation function to sigmoid for some of the layers.\n",
    "* Can you find a simple way of changing the activation function for all the layers?\n",
    "* Plot the output of the max-pooling layers instead of the conv-layers.\n",
    "* Replace the 2x2 max-pooling layers with stride=2 in the convolutional layers. Is there a difference in classification accuracy? What if you optimize it again and again? The difference is random, so how would you measure if there really is a difference? What are the pros and cons of using max-pooling vs. stride in the conv-layer?\n",
    "* Change the parameters for the layers, e.g. the kernel, depth, size, etc. What is the difference in time usage and classification accuracy?\n",
    "* Add and remove some convolutional and fully-connected layers.\n",
    "* What is the simplest network you can design that still performs well?\n",
    "* Change the Functional Model so it has another convolutional layer that connects in parallel to the existing conv-layers before going into the dense layers.\n",
    "* Change the Functional Model so it outputs the predicted class both as a One-Hot encoded array and as an integer, so we don't have to use `numpy.argmax()` afterwards.\n",
    "* Remake the program yourself without looking too much at this source-code.\n",
    "* Explain to a friend how the program works."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## License (MIT)\n",
    "\n",
    "Copyright (c) 2016-2017 by [Magnus Erik Hvass Pedersen](http://www.hvass-labs.org/)\n",
    "\n",
    "Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n",
    "\n",
    "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n",
    "\n",
    "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
